package com.study.web.controller.map;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaIgnore;
import com.study.common.core.controller.AppBaseController;
import com.study.common.core.domain.R;
import com.study.map.dto.*;
import com.study.map.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * 综合地图服务演示控制器
 *
 * @author study
 * @date 2025-08-31
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/map/all")
public class AllMapController extends AppBaseController {

    private final IGeoService geoService;
    private final IReGeoService reGeoService;
    private final IRouteService routeService;
    private final IDistrictService districtService;
    private final IWeatherService weatherService;
    private final IPoiService poiService;
    private final IIpLocationService ipLocationService;
    private final IStaticMapService staticMapService;
    private final ICoordConvertService coordConvertService;
    private final IInputTipsService inputTipsService;

    /**
     * 地理编码：将地址转换为经纬度坐标
     */
    @SaIgnore
    @GetMapping("/geo")
    public R<GeoResponse> geoCode(
            @RequestParam String address,
            @RequestParam(required = false) String city) {
        try {
            GeoResponse response = geoService.geoCode(address, city);
            return R.ok(response);
        } catch (Exception e) {
            return R.fail("地理编码失败: " + e.getMessage());
        }
    }

    /**
     * 逆地理编码：将经纬度坐标转换为地址
     */
    @SaIgnore
    @GetMapping("/regeo")
    public R<ReGeoResponse> reGeoCode(
            @RequestParam String longitude,
            @RequestParam String latitude) {
        try {
            ReGeoResponse response = reGeoService.reGeoCode(longitude, latitude);
            return R.ok(response);
        } catch (Exception e) {
            return R.fail("逆地理编码失败: " + e.getMessage());
        }
    }

    /**
     * 路径规划
     */
    @SaIgnore
    @GetMapping("/route")
    public R<RouteWalkingResponse> routePlan(
            @RequestParam String origin,
            @RequestParam String destination,
            @RequestParam(defaultValue = "driving") String type) {
        try {
            RouteWalkingResponse response = routeService.routePlan(origin, destination, type);
            return R.ok(response);
        } catch (Exception e) {
            return R.fail("路径规划失败: " + e.getMessage());
        }
    }

    /**
     * 行政区划查询
     */
    @SaIgnore
    @GetMapping("/district")
    public R<DistrictResponse> district(@RequestParam String keywords) {
        try {
            DistrictResponse response = districtService.district(keywords);
            return R.ok(response);
        } catch (Exception e) {
            return R.fail("行政区划查询失败: " + e.getMessage());
        }
    }


    /**
     * 天气查询
     * @param city
     * @param weatherType  天气类型: 1-实时天气，2-预报天气
     * @return
     */
    @SaIgnore
    @GetMapping("/weather")
    public R<WeatherResponse> weather(@RequestParam String city, @RequestParam(required = false, defaultValue = "1") Integer weatherType ) {
        try {
            WeatherResponse response = weatherService.weather(city, weatherType);
            return R.ok(response);
        } catch (Exception e) {
            return R.fail("天气查询失败: " + e.getMessage());
        }
    }

    /**
     * POI搜索
     */
    @SaIgnore
    @GetMapping("/poi")
    public R<PoiResponse> poiSearch(
            @RequestParam String keywords,
            @RequestParam String city) {
        try {
            PoiResponse response = poiService.poiSearch(keywords, city);
            return R.ok(response);
        } catch (Exception e) {
            return R.fail("POI搜索失败: " + e.getMessage());
        }
    }

    /**
     * IP定位
     */
    @SaIgnore
    @GetMapping("/ip")
    public R<IpLocationResponse> ipLocation(@RequestParam String ip) {
        try {
            IpLocationResponse response = ipLocationService.ipLocation(ip);
            return R.ok(response);
        } catch (Exception e) {
            return R.fail("IP定位失败: " + e.getMessage());
        }
    }

    /**
     * 静态地图
     */
    @SaIgnore
    @GetMapping("/static")
    public R<StaticMapResponse> staticMap(
            @RequestParam String location,
            @RequestParam(required = false, defaultValue = "10") Integer zoom,
            @RequestParam(required = false, defaultValue = "400") Integer size) {
        try {
            StaticMapRequest request = new StaticMapRequest();
            request.setLocation(location);
            request.setZoom(zoom);
            request.setSize(size);
            StaticMapResponse response = staticMapService.staticMap(request);
            return R.ok(response);
        } catch (Exception e) {
            return R.fail("静态地图生成失败: " + e.getMessage());
        }
    }

    /**
     * 坐标转换
     */
    @SaIgnore
    @GetMapping("/convert")
    public R<CoordConvertResponse> coordConvert(
            @RequestParam String locations,
            @RequestParam(defaultValue = "gps") String coordsys) {
        try {
            CoordConvertResponse response = coordConvertService.coordConvert(locations, coordsys);
            return R.ok(response);
        } catch (Exception e) {
            return R.fail("坐标转换失败: " + e.getMessage());
        }
    }

    /**
     * 输入提示
     */
    @SaIgnore
    @GetMapping("/tips")
    public R<InputTipsResponse> inputTips(
            @RequestParam String keywords,
            @RequestParam String city) {
        try {
            InputTipsResponse response = inputTipsService.inputTips(keywords, city);
            return R.ok(response);
        } catch (Exception e) {
            return R.fail("输入提示失败: " + e.getMessage());
        }
    }
}